#include "oj_common/oj_code_file.h"
namespace ojlb {
namespace oj_common {


OjCodeFile::OjCodeFile(
        const std::string& code_file_name,
        const std::string& programming_language,
        const std::string& version)
        : code_file_name_(code_file_name)
        , programming_language_(programming_language)
        , version_(version) {
    
    if (getProgrammingLanguage() == "c") {
        code_file_name_suffixs_ = { getCodeFileName() + ".c", getCodeFileName() + ".cout", getCodeFileName() + ".cerr", getCodeFileName() + ".cres" };
    } else if (getProgrammingLanguage() == "cpp") {
        code_file_name_suffixs_ = { getCodeFileName() + ".cc", getCodeFileName() + ".ccout", getCodeFileName() + ".ccerr", getCodeFileName() + ".ccres" };
    } else if (getProgrammingLanguage() == "java") {
        code_file_name_suffixs_ = { getCodeFileName() + ".java", getCodeFileName() + ".class", getCodeFileName() + ".javaerr", getCodeFileName() + ".javares" };
    } else if (getProgrammingLanguage() == "python") {
        code_file_name_suffixs_ = { getCodeFileName() + ".py", getCodeFileName() + ".py", getCodeFileName() + ".pyerr", getCodeFileName() + ".pyres" };
    } else {
        exit(-1);
        // TODO: 抛出异常
    }
}

std::string OjCodeFile::getCodeFileName() const { return code_file_name_; }

std::string OjCodeFile::getProgrammingLanguage() const { return programming_language_; }

std::string OjCodeFile::getVersion() const { return version_; }

std::string OjCodeFile::getSourcePath() const { return code_file_name_suffixs_[0]; }

std::string OjCodeFile::getObjectPath() const { return code_file_name_suffixs_[1]; }

std::string OjCodeFile::getErrorPath() const { return code_file_name_suffixs_[2]; }

std::string OjCodeFile::getResultPath() const { return code_file_name_suffixs_[3]; }

bool OjCodeFile::isExistOfSourcePath() const {
    struct stat temp;
    if (stat(getSourcePath().c_str(), &temp) == 0) {
        return true;
    } else {
        return false;
    }
}

bool OjCodeFile::isExistOfObjectPath() const {
    struct stat temp;
    if (stat(getObjectPath().c_str(), &temp) == 0) {
        return true;
    } else {
        return false;
    }
}

bool OjCodeFile::isExistOfErrorPath() const {
    struct stat temp;
    if (stat(getErrorPath().c_str(), &temp) == 0) {
        return true;
    } else {
        return false;
    }
}

bool OjCodeFile::isExistOfResultPath() const {
    struct stat temp;
    if (stat(getResultPath().c_str(), &temp) == 0) {
        return true;
    } else {
        return false;
    }
}

void OjCodeFile::deleteFile(const std::string& file_path) const {
    if (std::remove(file_path.c_str()) != 0) {
        OjLog::warn("无法写入字符串到不存在的 {} 文件", file_path);
    }
}

void OjCodeFile::deleteFile() const {
    deleteFile(getSourcePath());
    deleteFile(getObjectPath());
    deleteFile(getErrorPath());
    deleteFile(getResultPath());
}

void OjCodeFile::writeFile(const std::string& from_str, const std::string& to_file_path) const {
    std::ofstream outFile(to_file_path);
    if (!outFile.is_open()) {
        OjLog::warn("无法写入字符串到不存在的 {} 文件", to_file_path);
        return;
    }

    outFile << from_str;
    outFile.close();
    OjLog::info("Successfully wrote to file {}.", to_file_path);
}

void OjCodeFile::readFile(const std::string& from_file_path, std::string& to_str) const {
    std::ifstream inFile(from_file_path); // 打开文件
    if (!inFile.is_open()) {  // 检查文件是否成功打开
        OjLog::warn("无法读取不存在的 {} 文件到字符串", from_file_path);
        to_str = "";
        return;
    }

    std::stringstream buffer;
    buffer << inFile.rdbuf();
    to_str = buffer.str();

    inFile.close();
}



}
}